﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using Newtonsoft.Json;
using TvHeadend.Api;

namespace M3UToTvHeadend
{
	public partial class MainForm : Form
	{
		private List<Mux> _muxes;

		public MainForm()
		{
			InitializeComponent();
			Text = this.Text + " " + Assembly.GetEntryAssembly().GetName().Version;
		}

		private void _openFileButton_Click(object sender, EventArgs e)
		{
			if(_openFileDialog.ShowDialog(this) != DialogResult.OK)
				return;

			_fileNameTextBox.Text = _openFileDialog.FileName;
			SetLoadButtonEnabled();
		}

		private void SetLoadButtonEnabled()
		{
			_loadButton.Enabled = !string.IsNullOrWhiteSpace(_fileNameTextBox.Text) && (_udpCheckBox.Checked || _rtpCheckBox.Checked) && !string.IsNullOrWhiteSpace(_interfaceTextBox.Text);
		}

		private void _loadButton_Click(object sender, EventArgs e)
		{
			if(_openFileDialog.FileName == null)
				return;

			using(var api = new Client(_tvHeadendServerTextBox.Text, _usernameTextBox.Text, _passwordTextBox.Text))
			{
				var existing = api.MuxList();

				string filename = _openFileDialog.FileName;
				var lines = File.ReadAllLines(filename);

				_muxes = new List<Mux>();
				Mux tmp = null;
				foreach (var line in lines)
				{
					// #EXTINF:1,Nederland 1
					if (line.StartsWith("#EXTINF"))
					{
						tmp = new Mux();
						var split = line.Replace("ID:", "").Split(',', ':').Reverse();
						tmp.ServiceName = split.First();
						tmp.ChannelNumber = int.Parse(split.Skip(1).First());
					}
						// udp://@233.81.233.161:10294
					else if (_udpCheckBox.Checked && line.StartsWith("udp://"))
					{
						string url = line.Replace("@", "");
						tmp.Name = url;
						tmp.Url = url;
						tmp.Interface = _interfaceTextBox.Text;
						_muxes.Add(tmp);
					}
						// rtp://@224.0.251.135:8270
					else if (_rtpCheckBox.Checked && line.StartsWith("rtp://"))
					{
						string url = line.Replace("@", "");
						tmp.Name = url;
						tmp.Url = url;
						tmp.Interface = _interfaceTextBox.Text;
						_muxes.Add(tmp);
					}
				}

				_muxes = _muxes.OrderBy(m => m.ServiceName).ToList();

				_overviewCheckedListBox.BeginUpdate();
				_overviewCheckedListBox.Items.Clear();
				_overviewCheckedListBox.DisplayMember = "DisplayString";
				foreach (var mux in _muxes)
				{
					if(existing != null && existing.Muxes != null && !existing.Muxes.Any(m => m.Url == mux.Url))
						_overviewCheckedListBox.Items.Add(mux, true);
				}

				_overviewCheckedListBox.EndUpdate();
				_overViewGoupBox.Enabled = _muxes.Any();
				_exportGroupBox.Enabled = _muxes.Any();
				_exportButton.Enabled = _overviewCheckedListBox.CheckedItems.Count > 0;
				_setChannelNumbersButton.Enabled = _muxes.Any();
			}
		}

		private void _testConnectionButton1_Click(object sender, EventArgs e)
		{
			try
			{
				using(var bridge = new Client(_tvHeadendServerTextBox.Text, _usernameTextBox.Text, _passwordTextBox.Text))
				{
					var networkList = bridge.NetworkList();
					if(networkList != null && networkList.Networks != null)
					{
						_networkComboBox.BeginUpdate();
						_networkComboBox.Items.Clear();
						foreach (var network in networkList.Networks)
						{
							_networkComboBox.Items.Add(network);
						}
						_networkComboBox.EndUpdate();
						_networkComboBox.Enabled = true;
						if (_networkComboBox.Items.Count > 0)
							_networkComboBox.SelectedIndex = 0;
					}
					MessageBox.Show(this, "Succes!", "Succes!", MessageBoxButtons.OK, MessageBoxIcon.Information);
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(this, "Connection failed:" + Environment.NewLine + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		private void _exportButton_Click(object sender, EventArgs e)
		{
			try
			{
				var selected = _overviewCheckedListBox.CheckedItems.Cast<Mux>();
				var selectedNetwork = _networkComboBox.SelectedItem as Network;
				if (selectedNetwork == null)
					return;

				using(var api = new Client(_tvHeadendServerTextBox.Text, _usernameTextBox.Text, _passwordTextBox.Text))
				{
					foreach (var mux in selected)
					{
						api.MuxCreate(selectedNetwork.Id.ToString(), mux.ServiceName, mux.Url, mux.Interface);
					}
				}
				MessageBox.Show(this,
				                "All done!" + Environment.NewLine + "Now map the services on the Channel/EPG tab page in TvHeadend", "Succes", MessageBoxButtons.OK, MessageBoxIcon.Information);
			}
			catch (Exception ex)
			{
				MessageBox.Show(this, "Oops, something went wrong:" + Environment.NewLine + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		private void _udpCheckBox_CheckedChanged(object sender, EventArgs e)
		{
			SetLoadButtonEnabled();
		}

		private void _rtpCheckBox_CheckedChanged(object sender, EventArgs e)
		{
			SetLoadButtonEnabled();
		}

		private void _interfaceTextBox_TextChanged(object sender, EventArgs e)
		{
			SetLoadButtonEnabled();
		}

		private void _overviewCheckedListBox_ItemCheck(object sender, ItemCheckEventArgs e)
		{
		}

		private void _networkComboBox_SelectedIndexChanged(object sender, EventArgs e)
		{
			_inputGroupBox.Enabled = _networkComboBox.SelectedIndex != -1;
		}

		private void _overviewCheckedListBox_MouseUp(object sender, MouseEventArgs e)
		{
			_exportGroupBox.Enabled = _overviewCheckedListBox.CheckedItems.Count > 0;

		}

		private void _setChannelNumbersButton_Click(object sender, EventArgs e)
		{
			using (var api = new Client(_tvHeadendServerTextBox.Text, _usernameTextBox.Text, _passwordTextBox.Text))
			{
				int set = 0;
				var serviceList = api.ServiceList();
				if(serviceList != null && serviceList.Services != null)
				{
					var channelList = api.ChannelList();
					if (channelList != null && channelList.Channels != null)
					{
						foreach (var channel in channelList.Channels)
						{
							var node = api.Node(channel.Id);
							if(node == null || node.Nodes == null || !node.Nodes.Any())
								continue;
							var nodeDetails = node.Nodes.First();
							var services = nodeDetails.Params.FirstOrDefault(p => p.Id == "services");
							if(services == null)
								continue;
							var serviceIds = JsonConvert.DeserializeObject<string[]>(services.Value.ToString());
							if(!serviceIds.Any())
								continue;
							var serviceId = serviceIds.First();
							var service = serviceList.Services.FirstOrDefault(s => s.Id == serviceId);
							if(service==null)
								continue;
							
							var mux = _muxes.FirstOrDefault(m => string.Equals(m.Url, service.Multiplex));
							if (mux != null && channel.Number != mux.ChannelNumber)
							{
								api.SetChannelNumber(channel.Id, mux.ChannelNumber);
								set++;
							}
						}
					}
				}

				MessageBox.Show(this, string.Format("{0} channel numbers set", set), "Done", MessageBoxButtons.OK,
				                MessageBoxIcon.Information);
			}
		}
	}
}
